<template>
  <div class="utils-container">
    <h4>实体类属性提取</h4>
    <div class="part part1">
      <div class="item">
        <div class="title">输入实体类代码</div>
        <el-input
          v-model="entityInputText"
          style="width: 300px"
          :rows="defaultRows"
          type="textarea"
          placeholder="请输入Java实体类代码..."
        />
      </div>
      <el-button type="primary" @click="handleEntityGet()">提取属性</el-button>
      <div class="item">
        <div class="title">提取结果</div>
        <el-input
          v-model="entityOutputText"
          style="width: 300px"
          :rows="defaultRows"
          type="textarea"
          placeholder="提取的属性将显示在这里..."
          readonly
        />
      </div>
    </div>

    <h4>实体类大小写驼峰转换</h4>
    <div class="part part2">
      <div class="item">
        <div class="title">大写下划线格式</div>
        <el-input
          v-model="entityUpperText"
          style="width: 300px"
          :rows="defaultRows"
          type="textarea"
          placeholder="USER_NAME"
        />
        <div>
          <el-button type="primary" @click="handleEntityStringTransform(0)">转换</el-button>
        </div>
      </div>
      <div class="item">
        <div class="title">小写下划线格式</div>
        <el-input
          v-model="entityLowerText"
          style="width: 300px"
          :rows="defaultRows"
          type="textarea"
          placeholder="user_name"
        />
        <div>
          <el-button type="primary" @click="handleEntityStringTransform(1)">转换</el-button>
        </div>
      </div>
      <div class="item">
        <div class="title">驼峰格式</div>
        <el-input
          v-model="entityCamelText"
          style="width: 300px"
          :rows="defaultRows"
          type="textarea"
          placeholder="userName"
        />
        <div>
          <el-button type="primary" @click="handleEntityStringTransform(2)">转换</el-button>
        </div>
      </div>
      <div class="item">
        <div class="title">中划线格式</div>
        <el-input
          v-model="entityKebabText"
          style="width: 300px"
          :rows="defaultRows"
          type="textarea"
          placeholder="user-name"
        />
        <div>
          <el-button type="primary" @click="handleEntityStringTransform(3)">转换</el-button>
        </div>
      </div>
    </div>

    <h4>根据模板生成数据</h4>
    <div class="part part3">
      <div class="template-container">
        <!-- 模板输入区 -->
        <div class="template-section">
          <div class="template-header">
            <div class="title">模板前缀</div>
            <div class="template-actions">
              <el-select
                v-model="selectedTemplate"
                placeholder="选择预设模板"
                clearable
                value-key="name"
                @change="handleTemplateChange"
              >
                <el-option
                  v-for="item in presetTemplates"
                  :key="item.name"
                  :label="item.name"
                  :value="item"
                />
              </el-select>
              <el-button type="primary" link @click="handleExportConfig">
                导出配置
              </el-button>
            </div>
          </div>
          <el-input
            v-model="commonTemplateData.prefix"
            type="textarea"
            :rows="3"
            placeholder="请输入模板前缀，将会添加到生成内容的最前面"
          />
          <div class="template-header">
            <div class="title">模板内容</div>
          </div>
          <el-input
            v-model="commonTemplateData.template"
            type="textarea"
            :rows="3"
            placeholder="请输入模板，使用 {row1} 引用行数据，使用 {number1} 引用数字"
          />
          <div class="params">
            <div class="param-group">
              <div class="param-item">
                <el-radio-group v-model="commonTemplateData.lineMode" size="large">
                  <el-radio :label="0" border>自动行数</el-radio>
                  <el-radio :label="1" border>自定义行数</el-radio>
                </el-radio-group>
              </div>
              <div class="param-item">
                <el-input-number
                  v-model="commonTemplateData.line"
                  :min="1"
                  :max="1000"
                  placeholder="生成行数"
                  :disabled="commonTemplateData.lineMode === 0"
                  controls-position="right"
                />
              </div>
              <div class="param-item">
                <el-input
                  v-model="commonTemplateData.lineSplit"
                  placeholder="自定义分隔符(默认为换行)"
                  style="width: 200px"
                />
              </div>
            </div>
          </div>
        </div>

        <!-- 行数据输入区 -->
        <div class="data-section">
          <div class="section-title">
            <div class="title-group">
              <span>行数据填充</span>
              <el-radio-group v-model="commonTemplateData.rowFillMode" size="small">
                <el-radio :label="0" border>循环填充</el-radio>
                <el-radio :label="1" border>非循环填充</el-radio>
              </el-radio-group>
            </div>
            <div class="operations">
              <el-button type="primary" link @click="handleAddRow">
                <el-icon><Plus /></el-icon>添加行数据
              </el-button>
              <el-button link @click="rowExpanded = !rowExpanded">
                <el-icon><ArrowDown v-if="!rowExpanded" /><ArrowUp v-else /></el-icon>
                {{ rowExpanded ? '收起' : '展开' }}
              </el-button>
            </div>
          </div>
          <div class="row-container" :class="{ expanded: rowExpanded }">
            <div v-for="(item, index) in commonTemplateData.rowInsert" :key="index" class="row-item">
              <div class="title-row">
                <el-input
                  v-model="item.name"
                  placeholder="引用名称"
                  style="width: 120px"
                />
                <el-button type="danger" link @click="handleDeleteRow(index)">
                  <el-icon><Delete /></el-icon>删除
                </el-button>
              </div>
              <el-input
                v-model="item.value"
                type="textarea"
                :rows="10"
                :placeholder="`请输入${item.name}的数据`"
              />
            </div>
          </div>
        </div>

        <!-- 数字递增区 -->
        <div class="data-section">
          <div class="section-title">
            <span>数字递增设置</span>
            <div class="operations">
              <el-button type="primary" link @click="handleAddNumber">
                <el-icon><Plus /></el-icon>添加数字递增
              </el-button>
              <el-button link @click="numberExpanded = !numberExpanded">
                <el-icon><ArrowDown v-if="!numberExpanded" /><ArrowUp v-else /></el-icon>
                {{ numberExpanded ? '收起' : '展开' }}
              </el-button>
            </div>
          </div>
          <div class="number-container" :class="{ expanded: numberExpanded }">
            <div v-for="(item, index) in commonTemplateData.numberInsert" :key="index" class="number-item">
              <div class="title-row">
                <el-input
                  v-model="item.name"
                  placeholder="引用名称"
                  style="width: 120px"
                />
                <el-button type="danger" link @click="handleDeleteNumber(index)">
                  <el-icon><Delete /></el-icon>删除
                </el-button>
              </div>
              <div class="number-inputs">
                <div class="input-group">
                  <span class="label">起始值</span>
                  <el-input-number
                    v-model="item.start"
                    :placeholder="'起始值'"
                    :controls="false"
                    style="width: 120px"
                  />
                </div>
                <div class="input-group">
                  <span class="label">增量</span>
                  <el-input-number
                    v-model="item.add"
                    :placeholder="'增量'"
                    :controls="false"
                    style="width: 120px"
                  />
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 生成按钮和结果区 -->
        <div class="generate-section">
          <el-button type="primary" @click="getCommonTemplateResult">生成数据</el-button>
          <el-input
            v-model="commonTemplateData.result"
            type="textarea"
            :rows="10"
            placeholder="生成结果将显示在这里"
          />
        </div>
      </div>
    </div>
    
    <!-- 添加导出配置弹窗 -->
    <el-dialog
      v-model="exportDialogVisible"
      title="导出配置"
      width="600px"
    >
      <div class="export-dialog-content">
        <div class="export-form">
          <el-form :model="exportConfigForm" label-width="80px">
            <el-form-item label="模板名称">
              <el-input v-model="exportConfigForm.name" @input="updateExportConfig" />
            </el-form-item>
            <el-form-item label="模板描述">
              <el-input v-model="exportConfigForm.description" @input="updateExportConfig" />
            </el-form-item>
          </el-form>
        </div>
        <p class="export-tip">复制以下配置到 templates.js 文件中使用：</p>
        <el-input
          v-model="exportConfig"
          type="textarea"
          :rows="15"
          readonly
        />
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleCopyConfig">
            复制配置
          </el-button>
          <el-button @click="exportDialogVisible = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import Cookies from "js-cookie";
import useUserStore from '@/store/modules/user'
import { presetTemplates } from './templates'
import { Plus, Delete, ArrowDown, ArrowUp, DocumentAdd, DocumentCopy } from '@element-plus/icons-vue'

const userStore = useUserStore()
const route = useRoute()
const router = useRouter()
const { proxy } = getCurrentInstance()

const defaultRows = ref(10)

// ==============part1==============
const entityInputText = ref('')
const entityOutputText = ref('')
function handleEntityGet(){
  const entityList = entityInputText.value.split('\n')
  const entityResultList = []
  entityList.forEach(item => {
    let str = item.trim()
    if ((str.startsWith('private') || str.startsWith('public') || str.startsWith('protected')) && str.endsWith(';')){
      const type = str.split(' ')[1]
      const name = str.split(' ')[2].replace(';', '')
      entityResultList.push(`${name}`)
    }
  })
  entityOutputText.value = entityResultList.join('\n')
}
// ==============part2==============
const entityUpperText = ref('')
const entityLowerText = ref('')
const entityCamelText = ref('')
const entityKebabText = ref('')
function handleEntityStringTransform(type){
  let entityUpperList = entityUpperText.value.split('\n')
  let entityLowerList = entityLowerText.value.split('\n')
  let entityCamelList = entityCamelText.value.split('\n')
  let entityKebabList = entityKebabText.value.split('\n')
  if (type === 0){ // 大写
    entityCamelList = entityUpperList.map(item => {
      return upperToCamel(item)
    })
  } else if (type === 1){ // 小写
    entityCamelList = entityLowerList.map(item => {
      return lowerToCamel(item)
    })
  } else if (type === 3){ // 中划线
    entityCamelList = entityKebabList.map(item => {
      return kebabToCamel(item)
    })
  }
  entityUpperList = entityCamelList.map(item => {
    return camelToUpper(item)
  })
  entityLowerList = entityCamelList.map(item => {
    return camelToLower(item)
  })
  entityKebabList = entityCamelList.map(item => {
    return camelToKebab(item)
  })
  entityUpperText.value = entityUpperList.join('\n')
  entityLowerText.value = entityLowerList.join('\n')
  entityCamelText.value = entityCamelList.join('\n')
  entityKebabText.value = entityKebabList.join('\n')
}
function camelToUpper(str) {
  return str.replace(/([A-Z])/g, '_\$1').toUpperCase();
}
function camelToLower(str) {
  return str.replace(/([A-Z])/g, '_\$1').toLowerCase();
}
function upperToCamel(str) {
  return str.toLowerCase().replace(/_(.)/g, function(match, group1) {
    return group1.toUpperCase();
  });
}
function lowerToCamel(str) {
  return str.toLowerCase().replace(/_(.)/g, function(match, group1) {
    return group1.toUpperCase();
  });
}
function camelToKebab(str) {
  return str.replace(/([A-Z])/g, '-$1').toLowerCase();
}
function kebabToCamel(str) {
  return str.toLowerCase().replace(/-(.)/g, function(match, group1) {
    return group1.toUpperCase();
  });
}
// ==============part3==============
const commonTemplateData = ref({
  template: '',
  prefix: '',
  line: 100,
  lineMode: 0, // 0: 自动行数, 1: 自定义行数
  rowFillMode: 1, // 0: 循环填充, 1: 非循环填充
  lineSplit: '',
  rowInsert: [
    {
      name: '{row1}',
      value: ''
    },
    {
      name: '{row2}',
      value: ''
    },
    {
      name: '{row3}',
      value: ''
    },
    {
      name: '{row4}',
      value: ''
    },
    {
      name: '{row5}',
      value: ''
    },
  ],
  numberInsert: [
    {
      name: '{number1}',
      start: 0,
      add: 1
    },
    {
      name: '{number2}',
      start: 0,
      add: 1
    },
    {
      name: '{number3}',
      start: 0,
      add: 1
    },
    {
      name: '{number4}',
      start: 0,
      add: 1
    },
    {
      name: '{number5}',
      start: 0,
      add: 1
    },
  ],
  result: ''
})
function getCommonTemplateResult() {
  const { template, prefix, line, lineMode, lineSplit, rowInsert, numberInsert, rowFillMode } = commonTemplateData.value
  const split = lineSplit || '\n'
  let result = prefix || ''

  // 检查模板是否为空
  if (!template) {
    proxy.$message.warning('请输入模板内容')
    return
  }

  // 计算行数
  let lineCount = 100
  if (lineMode === 0) {
    // 自动行数模式：使用行数据填充中的最大行数
    lineCount = Math.max(...rowInsert
      .filter(item => item.value)
      .map(item => item.value.split('\n').length)) || 100
  } else {
    // 自定义行数模式
    lineCount = parseInt(line) || 100
  }
  
  for (let i = 0; i < lineCount; i++) {
    // 替换数字
    let currentTemplate = template
    numberInsert.forEach((item) => {
      if (item.name) {
        const currentNumber = Number(item.start) + i * Number(item.add)
        currentTemplate = currentTemplate.replace(
          new RegExp(item.name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
          currentNumber
        )
      }
    })

    // 替换行数据
    rowInsert.forEach((item) => {
      if (item.name && item.value) {
        const rowItems = item.value.split('\n')
        let rowValue = ''
        
        if (rowFillMode === 0) {
          // 循环填充模式
          rowValue = rowItems[i % rowItems.length] || ''
        } else {
          // 非循环填充模式
          rowValue = i < rowItems.length ? rowItems[i] : ''
        }
        
        currentTemplate = currentTemplate.replace(
          new RegExp(item.name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
          rowValue
        )
      }
    })

    result += currentTemplate + (i < lineCount - 1 ? split : '')
  }

  commonTemplateData.value.result = result
}

// 预设模板相关
const selectedTemplate = ref(null)

// 处理模板选择变化
function handleTemplateChange(template) {
  if (!template) {
    // 清空模板时重置为默认值
    commonTemplateData.value = {
      template: '',
      prefix: '',
      line: 100,
      lineMode: 0,
      rowFillMode: 1,
      lineSplit: '',
      rowInsert: [
        {
          name: '{row1}',
          value: ''
        }
      ],
      numberInsert: [
        {
          name: '{number1}',
          start: 0,
          add: 1
        }
      ],
      result: ''
    }
    return
  }
  
  // 应用预设模板的配置
  const { defaultConfig } = template
  commonTemplateData.value = {
    template: template.template,
    prefix: template.prefix || '',
    line: defaultConfig.line || 100,
    lineMode: defaultConfig.lineMode ?? 0,
    rowFillMode: defaultConfig.rowFillMode ?? 0,
    lineSplit: defaultConfig.lineSplit || '',
    rowInsert: defaultConfig.rowInsert?.map(item => ({
      name: item.name || `{row1}`,
      value: item.value || ''
    })) || [{
      name: '{row1}',
      value: ''
    }],
    numberInsert: defaultConfig.numberInsert?.map(item => ({
      name: item.name || `{number1}`,
      start: item.start ?? 0,
      add: item.add ?? 1
    })) || [{
      name: '{number1}',
      start: 0,
      add: 1
    }],
    result: ''
  }
}

// 添加行数据
function handleAddRow() {
  commonTemplateData.value.rowInsert.push({
    name: `{row${commonTemplateData.value.rowInsert.length + 1}}`,
    value: ''
  })
}

// 删除行数据
function handleDeleteRow(index) {
  commonTemplateData.value.rowInsert.splice(index, 1)
}

// 添加数字递增
function handleAddNumber() {
  commonTemplateData.value.numberInsert.push({
    name: `{number${commonTemplateData.value.numberInsert.length + 1}}`,
    start: 0,
    add: 1
  })
}

// 删除数字递增
function handleDeleteNumber(index) {
  commonTemplateData.value.numberInsert.splice(index, 1)
}

const rowExpanded = ref(false)
const numberExpanded = ref(false)

// 导出配置相关
const exportDialogVisible = ref(false)
const exportConfig = ref('')
const exportConfigForm = ref({
  name: '自定义模板',
  description: '自定义生成的模板配置'
})

// 处理导出配置
function handleExportConfig() {
  // 字符串转义处理函数
  const escapeString = (str) => {
    return str
      .replace(/\\/g, '\\\\')  // 转义反斜杠
      .replace(/'/g, "\\'")    // 转义单引号
      .replace(/\n/g, '\\n')   // 转义换行符
      .replace(/\r/g, '\\r')   // 转义回车符
      .replace(/\t/g, '\\t')   // 转义制表符
  }

  // 生成配置对象
  const config = {
    name: exportConfigForm.value.name,
    template: commonTemplateData.value.template,
    prefix: commonTemplateData.value.prefix,
    description: exportConfigForm.value.description,
    defaultConfig: {
      line: commonTemplateData.value.line,
      lineMode: commonTemplateData.value.lineMode,
      rowFillMode: commonTemplateData.value.rowFillMode,
      lineSplit: commonTemplateData.value.lineSplit,
      rowInsert: commonTemplateData.value.rowInsert.filter(item => item.name || item.value),
      numberInsert: commonTemplateData.value.numberInsert.filter(item => item.name)
    }
  }
  
  // 格式化配置对象为字符串，处理特殊字符
  exportConfig.value = `{
  name: '${escapeString(config.name)}',
  template: '${escapeString(config.template)}',
  prefix: '${escapeString(config.prefix)}',
  description: '${escapeString(config.description)}',
  defaultConfig: {
    line: ${config.defaultConfig.line},
    lineMode: ${config.defaultConfig.lineMode},
    rowFillMode: ${config.defaultConfig.rowFillMode},
    lineSplit: '${escapeString(config.defaultConfig.lineSplit)}',
    rowInsert: ${JSON.stringify(config.defaultConfig.rowInsert, null, 4)
      .split('\n')
      .map(line => '    ' + line)
      .join('\n')},
    numberInsert: ${JSON.stringify(config.defaultConfig.numberInsert, null, 4)
      .split('\n')
      .map(line => '    ' + line)
      .join('\n')}
  }
}`
  
  exportDialogVisible.value = true
}

// 更新导出配置
function updateExportConfig() {
  handleExportConfig()
}

// 复制配置到剪贴板
function handleCopyConfig() {
  navigator.clipboard.writeText(exportConfig.value).then(() => {
    proxy.$message.success('配置已复制到剪贴板')
    exportDialogVisible.value = false
  }).catch(() => {
    proxy.$message.error('复制失败，请手动复制')
  })
}

</script>

<style lang='scss' scoped>
.utils-container {
  padding: 20px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);

  h4 {
    margin: 20px 0;
    padding-left: 10px;
    border-left: 4px solid #409EFF;
    font-size: 18px;
  }

  .part {
    padding: 20px;
    background: #f8f9fa;
    border-radius: 6px;
    margin-bottom: 30px;

    .item {
      .title {
        font-size: 14px;
        color: #606266;
        margin-bottom: 10px;
        font-weight: 500;
      }

      :deep(.el-textarea__inner) {
        background-color: #fff;
        border: 1px solid #dcdfe6;
        
        &:focus {
          border-color: #409EFF;
        }
      }

      .el-button {
        margin-top: 10px;
        width: 100px;
      }
    }

    .item + .item {
      margin-left: 30px;
    }
  }

  .part1 {
    display: flex;
    align-items: flex-start;

    .el-button {
      margin: 30px;
      min-width: 80px;
    }
  }

  .part2 {
    display: flex;
  }

  .part3 {
    display: flex;
    
    span {
      color: #606266;
      font-size: 14px;
    }
  }
}

.template-container {
  width: 100%;
  
  .template-section {
    background: #fff;
    border-radius: 8px;
    padding: 20px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
    margin-bottom: 20px;
    
    .params {
      margin-top: 20px;
      
      .param-group {
        display: flex;
        flex-wrap: wrap;
        gap: 20px;
        align-items: center;
        
        .param-item {
          display: flex;
          align-items: center;
        }
      }
    }
  }

  .data-section {
    background: #fff;
    border-radius: 8px;
    padding: 20px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
    margin-bottom: 20px;
  }

  .section-title {
    font-size: 16px;
    font-weight: 500;
    margin-bottom: 15px;
    color: #606266;
    display: flex;
    justify-content: space-between;
    align-items: center;
    
    .title-group {
      display: flex;
      align-items: center;
      
      .el-radio-group {
        margin-left: 20px;
      }
    }

    .operations {
      margin-left: auto;
      display: flex;
      gap: 10px;
    }
  }

  .row-container {
    display: flex;
    gap: 20px;
    margin-bottom: 20px;
    overflow-x: auto;
    padding-bottom: 10px;
    
    &.expanded {
      flex-wrap: wrap;
      overflow-x: visible;
    }
    
    .row-item {
      flex: 0 0 300px;
      background: #f8f9fa;
      padding: 15px;
      border-radius: 6px;
      
      .title-row {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 12px;
      }
    }
  }

  .number-container {
    display: flex;
    gap: 20px;
    margin-bottom: 20px;
    overflow-x: auto;
    padding-bottom: 10px;
    flex-wrap: nowrap;

    &.expanded {
      flex-wrap: wrap;
      overflow-x: visible;
    }

    .number-item {
      flex: 0 0 300px;
      background: #f8f9fa;
      padding: 15px;
      border-radius: 6px;

      .title-row {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 12px;
      }
      
      .number-inputs {
        display: flex;
        gap: 20px;
        
        .input-group {
          display: flex;
          flex-direction: column;
          gap: 8px;
          
          .label {
            color: #606266;
            font-size: 14px;
          }
        }
      }
    }
  }

  .generate-section {
    background: #fff;
    border-radius: 8px;
    padding: 20px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
    display: flex;
    flex-direction: column;
    gap: 20px;
    align-items: flex-start;
  }
}

.template-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;

  .title {
    font-size: 16px;
    font-weight: 500;
    color: #606266;
  }

  .template-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    
    .el-select {
      width: 200px;
    }
  }
}

.template-option {
  padding: 8px 0;

  .template-name {
    font-size: 14px;
    color: #303133;
  }

  .template-desc {
    font-size: 12px;
    color: #909399;
    margin-top: 6px;
  }
}

.export-dialog-content {
  .export-form {
    margin-bottom: 20px;
  }
  
  .export-tip {
    margin: 0 0 10px;
    color: #606266;
    font-size: 14px;
  }
  
  :deep(.el-textarea__inner) {
    font-family: monospace;
    font-size: 14px;
  }
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>
